package com.jiangli.service.impl;

import com.jiangli.entity.Ingredient;
import com.jiangli.mapper.IngredientMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class IngredientServiceImpl {

    @Autowired
    private IngredientMapper ingredientMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    private static final String EMPTY_MARKER = "EMPTY";
    private static final String INGREDIENT_DISH_ID_PREFIX = "ingredient:dishIdsConnection:";

    public List<Long> getDishIdsByIngredientIds(List<Long> ids) { // 定义空集合标记字符串 private static final String EMPTY_MARKER = "EMPTY";
        List<String> dishIds = new ArrayList<>();
        for (Long id : ids) {
            if (id == null) {
                log.warn ("食材 id 为 null，跳过处理");
                continue;
            }

            String key = INGREDIENT_DISH_ID_PREFIX + id;
            boolean keyExists = Boolean.TRUE.equals(stringRedisTemplate.hasKey(key));
            List<String> dishIdsFromRedis = null;

            if (keyExists) {
                dishIdsFromRedis = stringRedisTemplate.opsForList().range(key, 0, -1);

// 处理 Redis 返回的空标记
                if (dishIdsFromRedis != null && dishIdsFromRedis.contains (EMPTY_MARKER)) {
                    dishIdsFromRedis = Collections.emptyList ();
                    log.info("Redis 中存在空标记，视为空列表处理");
                } else if (dishIdsFromRedis == null) {
                    dishIdsFromRedis = Collections.emptyList ();
                    log.warn ("Redis 返回 null，视为空列表处理");
                }
            } else {
                List<String> dishIdsFromDb = ingredientMapper.getDishIdWithIngredientId(id);

                if (dishIdsFromDb == null) {
                    dishIdsFromDb = Collections.emptyList ();
                    log.warn ("数据库查询返回 null，视为空列表处理");
                }

                if (CollectionUtils.isEmpty (dishIdsFromDb)) {
// 空集合时存入空标记字符串
                    stringRedisTemplate.opsForList().leftPush (key, EMPTY_MARKER);
                    stringRedisTemplate.expire (key, 1, TimeUnit.MINUTES);
                    dishIdsFromRedis = Collections.emptyList ();
                } else {
                    stringRedisTemplate.opsForList ().leftPushAll (key, dishIdsFromDb);
                    stringRedisTemplate.expire (key, 1, TimeUnit.HOURS);
                    dishIdsFromRedis = dishIdsFromDb;
                }
            }

            if (!dishIdsFromRedis.isEmpty()) {
                dishIds.addAll(dishIdsFromRedis);
            }
        }

        return dishIds.stream ()
                .filter (Objects::nonNull)
                .filter (s -> !s.trim ().isEmpty () && !s.trim ().equals (EMPTY_MARKER))
                .map (s -> {
                    try {
                        return Long.parseLong (s.trim ());
                    } catch (NumberFormatException e) {
                        log.error ("字符串转 Long 失败: {}", s, e);
                        return null;
                    }
                })
                .filter (Objects::nonNull)
                .collect (Collectors.toList ());
    }


    public List<Ingredient> getAllIngredientWithCache() {
        return ingredientMapper.selectAllAvailable();
    }
}
